<?php

require_once 'XML/Parser.php';

class dataModelParser extends XML_Parser
{
  private $schema = array();
  private $constraints = array();
  private $codeLookupData = array();

  private $currentTable = "";
  private $currentCodeColumn = "";
  private $currentCodeKey = 1;

  function myParser()
  {
    parent::XML_Parser();
  }

 /**
  * handle start element
  *
  * @access private
  * @param  resource  xml parser resource
  * @param  string    name of the element
  * @param  array     attributes
  */
  function startHandler($xp, $name, $attribs)
  {
	switch (strtolower($name))
	{
		case "schema" : break;
		case "table" :
			$this->currentTable = $attribs["NAME"];
			if ($this->currentTable != "")
			{
				$this->schema[$this->currentTable] = array();
				$column = array("name" => "id", "type" => "int", "length" => "8", "not-null" => "true");
				array_push($this->schema[$this->currentTable], $column);
				$this->constraints[$this->currentTable] = array();
				array_push($this->constraints[$this->currentTable], array("type" => "pk", "column" => "id"));
			}
			break;
		case "foreign-key" :
			if ($this->currentTable == "")
			{
				printf("foreign-key must exist inside of a table tag");
				break;
			}
			$foreignTable = $attribs["TABLE"];
			if (array_key_exists("NULL", $attribs))
			  $columnNullable = $attribs["NULL"];
			else
			  $columnNullable = "false";
			$columnName = $foreignTable . "_id";
			$column = array("name" => $columnName, "type" => "int", "length" => "8", "not-null" => ($columnNullable == "false") ? "true" : "false");
			array_push($this->schema[$this->currentTable], $column);
			array_push($this->constraints[$this->currentTable], array("type" => "fk", "foreignTable" => $foreignTable));
			break;
		case "codecolumn" :
			if ($this->currentTable == "")
			{
				$this->currentCodeColumn = $attribs["NAME"];
				$this->currentCodeKey = 1;
				break;
			}
			if (!isset($this->schema["code_lookup"]))
			{
				$column1 = array("name" => "id", "type" => "int", "length" => "8", "not-null" => "true");
				$column2 = array("name" => "name", "type" => "string", "length" => "40", "not-null" => "true");
				$column3 = array("name" => "code_key", "type" => "int", "length" => "8", "not-null" => "true");
				$column4 = array("name" => "value", "type" => "string", "length" => "50", "not-null" => "true");
				$this->schema["code_lookup"] = array($column1, $column2, $column3, $column4);
				$this->constraints["code_lookup"] = array();
				array_push($this->constraints["code_lookup"], array( "type" => "pk", "column" => "id"));
			}
			$this->currentCodeColumn = $attribs["NAME"];
			$column = array("name" => $this->currentCodeColumn, "type" => "int", "length" => "8", "not-null" => "true");
			array_push($this->schema[$this->currentTable], $column);
			$this->currentCodeKey = 1;
			break;
		case "codevalue" :
			if ($this->currentCodeColumn == "")
			{
				printf("codevalue must exist inside of a codecolumn tag");
				break;
			}
			if (isset($this->codeLookupData[$this->currentCodeColumn]))
			{
				$this->currentCodeKey = count($this->codeLookupData[$this->currentCodeColumn]) + 1;
			}
			else
			{
				$this->codeLookupData[$this->currentCodeColumn] = array();
			}
			$row = array("key" => $this->currentCodeKey, "value" => $attribs["TEXT"]);
			array_push($this->codeLookupData[$this->currentCodeColumn], $row);

			break;
		case "column" :
			if ($this->currentTable == "")
			{
				printf("column must exist inside of a table tag");
				break;
			}
			$columnName = $attribs["NAME"];
			$columnType = $attribs["TYPE"];
			if (array_key_exists("LENGTH", $attribs))
				$columnLength = $attribs["LENGTH"];
			else
				$columnLength = -1;
			if (array_key_exists("NOT-NULL", $attribs))
			  $columnNotNullable = $attribs["NOT-NULL"];
			else
			  $columnNotNullable = "false";
			$column = array("name" => $columnName, "type" => $columnType, "length" => $columnLength, "not-null" => $columnNotNullable);
			array_push($this->schema[$this->currentTable], $column);
			break;
	}

  }

 /**
  * handle start element
  *
  * @access private
  * @param  resource  xml parser resource
  * @param  string    name of the element
  */
  function endHandler($xp, $name)
  {
  	switch ($name)
	{
		case "table" : $this->currentTable = ""; break;
		case "codecolumn" : $this->currentCodeColumn = ""; break;
	}
  }

 /**
  * handle character data
  *
  * @access private
  * @param  resource  xml parser resource
  * @param  string    character data
  */
  function cdataHandler($xp, $cdata)
  {
    // does nothing here, but might e.g. print $cdata
  }

  function getSchema()
  {
    return $this->schema;
  }

  function getConstraints()
  {
    return $this->constraints;
  }

  function getCodeLookupData()
  {
    return $this->codeLookupData;
  }
}

?>
